package oj.util.SeContext;

import java.security.Security;
import java.util.Hashtable;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.rmi.PortableRemoteObject;

import oj.util.sUtil.CargarPropiedades;

public class SContext {
	private static Context SeContext;

	private CargarPropiedades contextExterno;

	private Object jndi;

	private String host;

	private String port;

	private String protocol;

	private static Hashtable Scontexto;

	public SContext() {

		try {

			// Hashtable environment = new Contexto.getScontexto();

			Hashtable environment = getContexto();
			Properties props = new Properties();

			// props.

			SeContext = new InitialContext(environment);
			System.out.println("Inicio el SeContext");

			// Seteo el Contexto
			setSeContext(SeContext);

		} catch (Exception e) {
			try {
				throw new Exception("Error de Conexcion");
			} catch (Exception e1) {
				e.printStackTrace();
			}
		}

	}

	public Object getHome(String homeName, Class homeClass)
			throws NamingException, Exception {
		Object boundObject = null;
		try {

			boundObject = getSeContext().lookup(homeName);
		} catch (Exception e) {
			throw new Exception("Error al cargar el Contexto");
		}

		return PortableRemoteObject.narrow(boundObject, homeClass);

	}

	public Hashtable getContexto() {

		Hashtable env = null;
		try {

			// CARGO LAS Propiedades del Jboss
			CargarPropiedades prop = new CargarPropiedades();
			this.host = prop.getIP();
			this.port = prop.getPORT();
			this.protocol = prop.getPROTOCOL();

			// Setea el environment con el Servidor de EJB
			env = setProperties(host, port, protocol);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return env;
	}

	private Hashtable setProperties(String host, String port, String protocol) {

		Hashtable env = new Hashtable();

		try {
			try {
				String ipProvider = host;
				if (port != null) {
					ipProvider += ":" + port;
				}

				if (protocol.equals("RMI")) {
					// RMI
					env.put(Context.INITIAL_CONTEXT_FACTORY,
							"org.jnp.interfaces.NamingContextFactory");
					env.put(Context.PROVIDER_URL, ipProvider);
				} else {
					String p = "http://";
					String factory = "JNDIFactory";
					if (protocol.equals("SSL")) {
						initSSL();
					}
					if (protocol.equals("HTTPS") || protocol.equals("SSL")) {
						p = "https://";
						Security
								.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
						System.setProperty("java.protocol.handler.pkgs",
								"javax.net.ssl");
					}
					// HTTP Tunnelling
					env.put(Context.INITIAL_CONTEXT_FACTORY,
							"org.jboss.naming.HttpNamingContextFactory");
					env.put(Context.PROVIDER_URL, p + ipProvider + "/invoker/"
							+ factory);
				}

				env.put("java.naming.factory.url.pkgs",
						"org.jboss.naming:org.jnp.interfaces");

				env.put("jnp.socketFactory",
						"org.jnp.interfaces.TimedSocketFactory");
				env.put("jnp.timeout", "0");
				env.put("jnp.sotimeout", "0");

				// Seteo el contexto
				setScontexto(env);

			} catch (Exception ex) {
				System.out.println("Context error");
				ex.printStackTrace();
				System.out.println("Context error");
			}

		} catch (Exception e) {

		}

		return env;
	}

	private void initSSL() {

		// System.setProperty("javax.net.debug", "ssl");
		System.setProperty("javax.net.ssl.keyStore", "sapiensssl");
		System.setProperty("javax.net.ssl.keyStorePassword", "sapiensssl");
		System.setProperty("javax.net.ssl.trustStore", "sapiensssl");
		System.setProperty("javax.net.ssl.trustStorePassword", "sapiensssl");

		HostnameVerifier hv = new HostnameVerifier() {
			public boolean verify(String urlHostname, SSLSession session) {
				// System.out.println();println("HostnameVerifier::verify.");
				return true;
			}
		};
		HttpsURLConnection.setDefaultHostnameVerifier(hv);
	}

	public Context getSeContext() {
		return SeContext;
	}

	private void setSeContext(Context seContext) {
		SeContext = seContext;
	}

	private CargarPropiedades getContextExterno() {
		this.contextExterno = new CargarPropiedades();
		return contextExterno;
	}

	private void setContextExterno(CargarPropiedades contextExterno) {
		this.contextExterno = contextExterno;
	}

	private Object getJndi() {
		return jndi;
	}

	private void setJndi(Object jndi) {
		this.jndi = jndi;
	}

	private String getHost() {
		return host;
	}

	private void setHost(String host) {
		this.host = host;
	}

	private String getPort() {
		return port;
	}

	private void setPort(String port) {
		this.port = port;
	}

	private String getProtocol() {
		return protocol;
	}

	private void setProtocol(String protocol) {
		this.protocol = protocol;
	}

	private static Hashtable getScontexto() {
		return Scontexto;
	}

	private static void setScontexto(Hashtable scontexto) {
		Scontexto = scontexto;
	}

}
